from fastapi import APIRouter, Depends, HTTPException, Request
from sqlalchemy.orm import Session
from pydantic import BaseModel
from typing import Optional
from utils.database import get_db
from Models.login.models import User, RealNameAuth
from Models.login.schemas import RealNameAuthSchema
from Views.home.Profile.AccessToken import GetAccess
from utils import JWTUtils
from utils.redis_utils import get_redis
import uuid
import json
from datetime import datetime

router = APIRouter(prefix="/auth", tags=["实名认证"])

class VerifyRequest(BaseModel):
    image_url: Optional[str] = None  # 七牛云URL（可选）
    image_data: Optional[str] = None  # Base64图片数据（可选）

class VerificationResponse(BaseModel):
    success: bool
    task_id: Optional[str] = None
    message: Optional[str] = None


#接口接收用户上传的身份证图片
@router.post("/verify-idcard", response_model=VerificationResponse)
async def verify_idcard(request: Request, data: VerifyRequest, db: Session = Depends(get_db)):
    """实名认证接口 - 异步队列模式
    功能：
    验证用户JWT Token获取user_id
    检查用户是否已认证（User.is_verified）
    接收用户上传的身份证图片（URL或Base64）
    生成任务ID并加入Redis队列idcard_ocr_queue
    保存任务初始状态到Redis哈希表RZ:{user_id}:idcard_ocr_tasks
    支持两种方式：
    1. image_url: 七牛云或其他图片URL
    2. image_data: Base64编码的图片数据（data:image/...格式或纯base64字符串）
    """
    # 从 JWT Token 获取用户ID
    authorization = request.headers.get("Authorization")
    if not authorization or not authorization.startswith("Bearer "):
        raise HTTPException(status_code=401, detail="未登录或token无效")

    try:
        token = authorization.split(" ")[1]
        payload = JWTUtils.decode_access_token(token)
        if not payload or not payload.get("user_id"):
            raise HTTPException(status_code=401, detail="token非法或已过期")
        user_id = payload["user_id"]
    except (IndexError, KeyError):
        raise HTTPException(status_code=401, detail="token格式错误")

    # 验证用户是否存在
    user = db.query(User).filter(User.id == user_id).first()
    if not user:
        raise HTTPException(status_code=404, detail="用户不存在")

    # 检查用户是否已经认证
    if user.is_verified == 1:
        raise HTTPException(status_code=400, detail="用户已经完成实名认证")

    # 验证至少提供了image_url或image_data之一
    if not data.image_url and not data.image_data:
        raise HTTPException(status_code=400, detail="请提供图片URL或图片数据")

    ## 生成任务ID和任务数据##
    task_id = str(uuid.uuid4())
    task_data = {
        "task_id": task_id,
        "user_id": user_id,
        "created_at": str(datetime.now())
    }
    
    # 如果提供了image_url，使用URL
    if data.image_url:
        task_data["image_url"] = data.image_url
    # 如果提供了image_data，使用base64数据
    elif data.image_data:
        task_data["image_data"] = data.image_data

    redis_client = get_redis()
    redis_client.rpush("idcard_ocr_queue", json.dumps(task_data))
    # 保存任务初始状态（按用户分组，方便查询）
    redis_client.hset(f"RZ:{user_id}:idcard_ocr_tasks", task_id, json.dumps({
        "status": "pending",
        "message": "排队中，请稍候...",
        "timestamp": datetime.now().isoformat()
    }))

    return VerificationResponse(
        success=True,
        task_id=task_id,
        message="认证任务已提交，处理结果将通过系统消息通知您"
    )


#接口获取用户的系统消息（实名认证结果）
@router.get("/messages", response_model=dict)
async def get_system_messages(request: Request, db: Session = Depends(get_db)):
    """从请求头的 Authorization 字段获取 JWT token
        解析 token 获取 user_id
        验证 token 的有效性"""
    authorization = request.headers.get("Authorization")
    if not authorization or not authorization.startswith("Bearer "):
        raise HTTPException(status_code=401, detail="未登录或token无效")

    try:
        token = authorization.split(" ")[1]
        payload = JWTUtils.decode_access_token(token)
        if not payload or not payload.get("user_id"):
            raise HTTPException(status_code=401, detail="token非法或已过期")
        user_id = payload["user_id"]
    except (IndexError, KeyError):
        raise HTTPException(status_code=401, detail="token格式错误")

    redis_client = get_redis()
    messages = []
    
    # 1. 从Redis通知队列获取消息（最近的）
    notification_key = f"ws_notifications:{user_id}"
    # 获取哪的100条信息
    notification_list = redis_client.lrange(notification_key, 0, 99)
    
    for notif_json in notification_list:
        try:
            notif = json.loads(notif_json)
            if notif.get("type") == "verify_result":
                messages.append({
                    "id": notif.get("task_id", f"msg_{hash(notif_json)}"),
                    "type": notif.get("type"),
                    "status": notif.get("status"),
                    "title": "实名认证成功" if notif.get("status") == "success" else "实名认证失败",
                    "message": notif.get("message", ""),
                    "data": notif.get("data"),
                    "timestamp": notif.get("timestamp"),
                    "read": False  # 默认未读
                })
        except Exception as e:
            continue
    
    # 2. 从任务状态哈希表获取获取 OCR 认证任务状态
    tasks_key = f"RZ:{user_id}:idcard_ocr_tasks"
    all_tasks = redis_client.hgetall(tasks_key)
    
    for task_id, task_json in all_tasks.items():
        try:
            task_data = json.loads(task_json)
            # 检查是否已经在messages中（避免重复）
            exists = any(msg.get("id") == task_id for msg in messages)
            if not exists and task_data.get("status") in ["success", "failed"]:
                # 从任务数据中获取timestamp，如果没有则使用当前时间
                msg_timestamp = task_data.get("timestamp")
                if not msg_timestamp:
                    # 尝试从任务创建时间推断
                    msg_timestamp = datetime.now().isoformat()
                
                messages.append({
                    "id": task_id,
                    "type": "verify_result",
                    "status": task_data.get("status"),
                    "title": "实名认证成功" if task_data.get("status") == "success" else "实名认证失败",
                    "message": task_data.get("message", ""),
                    "data": task_data.get("data"),
                    "timestamp": msg_timestamp,
                    "read": False
                })
        except Exception:
            continue
    
    # 按时间倒序排序
    messages.sort(key=lambda x: x.get("timestamp", ""), reverse=True)
    
    return {
        "code": 200,
        "message": "success",
        "data": messages
    }


#获取当前用户的实名认证详情
@router.get("/verification-detail", response_model=dict)
async def get_verification_detail(request: Request, db: Session = Depends(get_db)):
    """获取当前用户的实名认证详情"""
    # 从 JWT Token 获取用户ID
    authorization = request.headers.get("Authorization")
    if not authorization or not authorization.startswith("Bearer "):
        raise HTTPException(status_code=401, detail="未登录或token无效")

    try:
        token = authorization.split(" ")[1]
        payload = JWTUtils.decode_access_token(token)
        if not payload or not payload.get("user_id"):
            raise HTTPException(status_code=401, detail="token非法或已过期")
        user_id = payload["user_id"]
    except (IndexError, KeyError):
        raise HTTPException(status_code=401, detail="token格式错误")

    # 验证用户是否存在
    user = db.query(User).filter(User.id == user_id).first()
    if not user:
        raise HTTPException(status_code=404, detail="用户不存在")

    # 如果用户未认证，返回空数据
    if not user.is_verified:
        return {
            "code": 200,
            "message": "用户尚未完成实名认证",
            "data": None
        }

    # 查询认证详情
    verification = db.query(RealNameAuth).filter(RealNameAuth.user_id == user_id).order_by(RealNameAuth.created_at.desc()).first()
    
    if not verification:
        # 如果查询不到认证记录，但is_verified为True，需要修正状态
        if user.is_verified:
            user.is_verified = False
            db.commit()
        return {
            "code": 200,
            "message": "未找到认证信息",
            "data": None
        }

    # 身份证号脱敏处理（显示前6位和后4位，中间用*替代）
    id_number = verification.id_number
    if len(id_number) > 10:
        masked_id_number = id_number[:6] + "*" * (len(id_number) - 10) + id_number[-4:]
    else:
        masked_id_number = "*" * len(id_number)

    return {
        "code": 200,
        "message": "success",
        "data": {
            "real_name": verification.real_name,
            "id_number": masked_id_number,  # 脱敏后的身份证号
            "address": verification.address,
            "created_at": verification.created_at.isoformat() if verification.created_at else None,
            "idcard_image_url": verification.idcard_image_url
        }
    }